import { Request, Response } from 'express';
import sysConfigService from '@/services/system/sys-config.service';
import ApiResponse from '@/utils/api/api-response.util';
import { getLogger } from '@/utils/logger';
import { ConfigQueryParams, ConfigFormData } from '@/types/system/config';
import { ExcelUtil } from '@/utils';
import { Log, BusinessType } from '@/decorators/Log';
import { RepeatSubmit } from '@/decorators/repeatSubmit.decorator';
import { AuthRequest } from '@/types';

// 创建模块专用的日志记录器
const consoleLogger = getLogger("sys-config-controller");
const logger = getLogger("sys-config-controller", {
	console: false,
});

/**
 * 参数配置 控制器
 * 对应Java: SysConfigController
 */
class SysConfigController {
  /**
   * 获取参数配置列表（分页、条件）
   * @param req 请求对象
   * @param res 响应对象
   */
  async list(req: Request, res: Response) {
    try {
      // 请求日志
      consoleLogger.info("获取参数配置列表请求", {
        query: req.query,
        operator: req.user?.userName || 'unknown',
      });
      
      const params: ConfigQueryParams = req.query;
      const result = await sysConfigService.getConfigList(params);
      
      // 结果日志
      logger.info("获取参数配置列表成功", {
        response: {
          total: result.total,
          count: result.rows.length,
          pageNum: result.pageNum,
          pageSize: result.pageSize,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.successWithTable(res, result.rows, result.total, '查询成功', result.pageNum, result.pageSize);
    } catch (error) {
      // 详细的错误日志
      consoleLogger.error(`获取参数配置列表失败: ${error instanceof Error ? error.message : String(error)}`, {
        requestData: {
          query: req.query,
        },
        operator: req.user?.userName || 'unknown',
        stack: error instanceof Error ? error.stack : undefined
      });
      if (!res.headersSent) {
        ApiResponse.error(res, '获取参数配置列表失败', 500);
      }
    }
  }

  /**
   * 获取参数详细信息
   * @param req 请求对象
   * @param res 响应对象
   */
  async getInfo(req: Request, res: Response) {
    try {
      const configId = Number(req.params.configId);
      
      // 请求日志
      consoleLogger.info("获取参数详细信息请求", {
        params: req.params,
        configId,
        operator: req.user?.userName || 'unknown',
      });
      
      const data = await sysConfigService.getConfigById(configId);
      
      if (!data) {
        consoleLogger.warn('获取参数详细信息 - 参数不存在', { configId });
        ApiResponse.error(res, '参数不存在', 404);
        return;
      }
      
      // 结果日志
      logger.info("获取参数详细信息成功", {
        response: {
          configId,
          configKey: data.configKey,
          configName: data.configName,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.success(res, data, '查询成功');
    } catch (error) {
      // 详细的错误日志
      consoleLogger.error(`获取参数配置详情失败: ${error instanceof Error ? error.message : String(error)}`, {
        requestData: {
          params: req.params,
        },
        operator: req.user?.userName || 'unknown',
        stack: error instanceof Error ? error.stack : undefined
      });
      if (!res.headersSent) {
        ApiResponse.error(res, '获取参数配置详情失败', 500);
      }
    }
  }

  /**
   * 根据参数键名查询参数值
   * @param req 请求对象
   * @param res 响应对象
   */
  async getConfigKey(req: Request, res: Response) {
    try {
      const { configKey } = req.params;
      
      // 请求日志
      consoleLogger.info("根据参数键名查询参数值请求", {
        params: req.params,
        configKey,
        operator: req.user?.userName || 'unknown',
      });
      
      const value = await sysConfigService.getConfigValueByKey(configKey);
      
      // 结果日志
      logger.info("根据参数键名查询参数值成功", {
        response: {
          configKey,
          value,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.success(res, value, '查询成功');
    } catch (error) {
      // 详细的错误日志
      consoleLogger.error(`根据参数键名查询参数值失败: ${error instanceof Error ? error.message : String(error)}`, {
        requestData: {
          params: req.params,
        },
        operator: req.user?.userName || 'unknown',
        stack: error instanceof Error ? error.stack : undefined
      });
      if (!res.headersSent) {
        ApiResponse.error(res, '查询参数值失败', 500);
      }
    }
  }

  /**
   * 新增参数配置
   * @param req 请求对象
   * @param res 响应对象
   */
  @RepeatSubmit({ expireSeconds: 5 })
  @Log({ title: '参数配置', businessType: BusinessType.INSERT })
  async add(req: AuthRequest, res: Response) {
    try {
      const data: ConfigFormData = req.body;
      
      // 请求日志
      consoleLogger.info("新增参数配置请求", {
        body: req.body,
        operator: req.user?.userName || 'unknown',
      });
      
      // 获取当前登录用户名
      data.createBy = req.user?.userName || 'admin';
      await sysConfigService.createConfig(data);
      
      // 结果日志
      logger.info("新增参数配置成功", {
        response: {
          configKey: data.configKey,
          configName: data.configName,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.success(res, null, '新增成功');
    } catch (error) {
      // 详细的错误日志
      consoleLogger.error(`新增参数配置失败: ${error instanceof Error ? error.message : String(error)}`, {
        requestData: {
          body: req.body,
        },
        operator: req.user?.userName || 'unknown',
        stack: error instanceof Error ? error.stack : undefined
      });
      if (!res.headersSent) {
        ApiResponse.error(res, '新增参数配置失败', 500);
      }
    }
  }

  /**
   * 修改参数配置
   * @param req 请求对象
   * @param res 响应对象
   */
  @RepeatSubmit({ expireSeconds: 5 })
  @Log({ title: '参数配置', businessType: BusinessType.UPDATE })
  async edit(req: AuthRequest, res: Response) {
    try {
      const data: ConfigFormData = req.body;
      
      // 请求日志
      consoleLogger.info("修改参数配置请求", {
        body: req.body,
        operator: req.user?.userName || 'unknown',
      });
      
      // 获取当前登录用户名
      data.updateBy = req.user?.userName || 'admin';
      await sysConfigService.updateConfig(Number(data.configId), data);
      
      // 结果日志
      logger.info("修改参数配置成功", {
        response: {
          configId: data.configId,
          configKey: data.configKey,
          configName: data.configName,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.success(res, null, '修改成功');
    } catch (error) {
      // 详细的错误日志
      consoleLogger.error(`修改参数配置失败: ${error instanceof Error ? error.message : String(error)}`, {
        requestData: {
          body: req.body,
        },
        operator: req.user?.userName || 'unknown',
        stack: error instanceof Error ? error.stack : undefined
      });
      if (!res.headersSent) {
        ApiResponse.error(res, '修改参数配置失败', 500);
      }
    }
  }

  /**
   * 删除参数配置
   * @param req 请求对象
   * @param res 响应对象
   */
  @Log({ title: '参数配置', businessType: BusinessType.DELETE })
  async remove(req: AuthRequest, res: Response) {
    try {
      const configIds = req.params.configIds.split(',').map(id => parseInt(id));
      
      // 请求日志
      consoleLogger.info("删除参数配置请求", {
        params: req.params,
        configIds,
        operator: req.user?.userName || 'unknown',
      });
      
      await sysConfigService.deleteConfig(configIds);
      
      // 结果日志
      logger.info("删除参数配置成功", {
        response: {
          configIds,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.success(res, null, '删除成功');
    } catch (error) {
      // 详细的错误日志
      consoleLogger.error(`删除参数配置失败: ${error instanceof Error ? error.message : String(error)}`, {
        requestData: {
          params: req.params,
        },
        operator: req.user?.userName || 'unknown',
        stack: error instanceof Error ? error.stack : undefined
      });
      if (!res.headersSent) {
        ApiResponse.error(res, '删除参数配置失败', 500);
      }
    }
  }

  /**
   * 刷新参数缓存
   * @param req 请求对象
   * @param res 响应对象
   */
  async refreshCache(req: Request, res: Response) {
    try {
      // 请求日志
      consoleLogger.info("刷新参数缓存请求", {
        operator: req.user?.userName || 'unknown',
      });
      
      await sysConfigService.refreshCache();
      
      // 结果日志
      logger.info("刷新参数缓存成功", {
        operator: req.user?.userName || 'unknown',
      });
      
      ApiResponse.success(res, null, '缓存刷新成功');
    } catch (error) {
      // 详细的错误日志
      consoleLogger.error(`刷新参数缓存失败: ${error instanceof Error ? error.message : String(error)}`, {
        operator: req.user?.userName || 'unknown',
        stack: error instanceof Error ? error.stack : undefined
      });
      if (!res.headersSent) {
        ApiResponse.error(res, '刷新参数缓存失败', 500);
      }
    }
  }

  /**
   * 导出参数配置
   * @param req 请求对象
   * @param res 响应对象
   */
  @Log({ title: '参数配置', businessType: BusinessType.EXPORT })
  async export(req: Request, res: Response) {
    try {
      // 请求日志
      consoleLogger.info("导出参数配置Excel请求", {
        body: req.body,
        operator: req.user?.userName || 'unknown',
      });
      
      const params: ConfigQueryParams = req.body;
      // 查询全部参数配置（不分页）
      const result = await sysConfigService.getConfigList({ ...params, pageNum: 1, pageSize: 10000 });
      
      // 定义导出字段
      const fields = [
        { header: '参数主键', key: 'configId', width: 10 },
        { header: '参数名称', key: 'configName', width: 20 },
        { header: '参数键名', key: 'configKey', width: 20 },
        { header: '参数键值', key: 'configValue', width: 30 },
        { header: '系统内置', key: 'configType', width: 10 },
        { header: '备注', key: 'remark', width: 30 },
        { header: '创建者', key: 'createBy', width: 15 },
        { header: '创建时间', key: 'createTime', width: 20, type: 'datetime' },
        { header: '更新者', key: 'updateBy', width: 15 },
        { header: '更新时间', key: 'updateTime', width: 20, type: 'datetime' },
      ];
      
      // 优雅映射系统内置字段
      const configTypeMap = new Map([
        ['Y', '是'],
        ['N', '否']
      ]);
      
      const exportRows = result.rows.map(row => ({
        ...row,
        configType: configTypeMap.get(row.configType) ?? row.configType
      }));
      
      await ExcelUtil.exportToResponse(res, exportRows, fields, `参数配置_${Date.now()}`);
      
      // 结果日志
      logger.info("导出参数配置Excel成功", {
        response: {
          total: result.total,
          count: result.rows.length,
        },
        operator: req.user?.userName || 'unknown',
      });
      
      res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
      res.setHeader('Content-Disposition', 'attachment; filename="config.xlsx"');
      res.end(Buffer);
    } catch (error) {
      // 详细的错误日志
      consoleLogger.error(`导出参数配置失败: ${error instanceof Error ? error.message : String(error)}`, {
        requestData: {
          body: req.body,
        },
        operator: req.user?.userName || 'unknown',
        stack: error instanceof Error ? error.stack : undefined
      });
      if (!res.headersSent) {
        ApiResponse.error(res, '导出参数配置失败', 500);
      }
    }
  }
}

export default new SysConfigController(); 